1 : <?php
2 : /*--------------------------------------------------------------------------+
3 : This file is part of eStudy.
4 : suchmaschine/classes/class.pluginzip.inc.php
5 : - Modulgruppe: Suche
6 : - Beschreibung: In dieser Datei wird die Klasse PluginZip implementiert.
7 : - Version: 0.2 01/17/08
8 : - Autor(en): Jörg Rieger
9 : +---------------------------------------------------------------------------+
10 : This program is free software; you can redistribute it and/or
11 : modify it under the terms of the GNU General Public License
12 : as published by the Free Software Foundation; either version 2
13 : of the License, or any later version.
14 : +---------------------------------------------------------------------------+
15 : This program is distributed in the hope that it will be useful,
16 : but WITHOUT ANY WARRANTY; without even the implied warranty of
17 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 : GNU General Public License for more details.
19 : You should have received a copy of the GNU General Public License
20 : along with this program; if not, write to the Free Software
21 : Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 : +--------------------------------------------------------------------------*/
23 :
24 : /**
25 : * Path to Root falls nicht gesetzt
26 : */
27 : if ( !defined('PATH_TO_ROOT') ) {
28 : define("PATH_TO_ROOT", "../../");
29 :
30 : require_once('class.iindexer.inc.php');
31 : require_once('class.indexer.inc.php');
32 :
33 : }
34 :
35 : if ( !defined('TMP_DIR') ) {
36 : global $settings;
37 : define('TMP_DIR', PATH_TO_ROOT . $settings['upload_path'] . 'such_tmp/');
38 : }
39 :
40 :
41 :
42 : /**
43 : * Klasse PluginZip
44 : *
45 : * @package eStudy.Suchmaschine
46 : * @version 0.1 01/08/08
47 : * @author Jörg Rieger
48 : */
49 : class PluginZip extends Indexer {
50 : private $za;
51 :
52 : /**
53 : * Kontruktor
54 : *
55 : * @access public
56 : */
57 : public function __construct() {
58 :
59 : // PHP muss mit --enable-zip komipiliert worden sein
60 0 : if (class_exists('ZipArchive')) {
61 0 : $this->name = 'ZIP';
62 :
63 0 : $this->fileExt = array("zip",
64 0 : "sxw", // OpenOffice 1.x - Textdokument
65 0 : "stw", // OpenOffice 1.x - Textdokumentvorlage
66 0 : "sxc", // OpenOffice 1.x - Tabellendokument
67 0 : "stc", // OpenOffice 1.x - Tabellendokumentvorlage
68 0 : "sxi", // OpenOffice 1.x - Präsentation
69 0 : "sti", // OpenOffice 1.x - Präsentationsvorlage
70 0 : "odt", // OpenOffice 2.x - Textdokument
71 0 : "ott", // OpenOffice 2.x - Textdokumentvorlage
72 0 : "ods", // OpenOffice 2.x - Tabellendokument
73 0 : "ots", // OpenOffice 2.x - Tabellendokumentvorlage
74 0 : "odp", // OpenOffice 2.x - Präsentation
75 : "odt" // OpenOffice 2.x - Präsentationsvorlage
76 0 : );
77 :
78 0 : $this->za = new ZipArchive();
79 0 : }
80 : else {
81 0 : $this->name = 'Void';
82 0 : $this->fileExt = array();
83 : }
84 0 : }
85 :
86 : /**
87 : * Öffnen der Datei
88 : *
89 : * @access public
90 : */
91 : public function open( $fileName ) {
92 0 : if ( !file_exists($fileName) )
93 0 : throw new Exception('Datei ' . $fileName . ' existiert nicht');
94 :
95 0 : if ( $this->za->open(realpath($fileName)) !== true )
96 0 : throw new Exception('Zip Datei ' . $fileName . ' konnte nicht geöffnet werden');
97 0 : }
98 :
99 : /**
100 : * Zurückgeben des Inhalts
101 : *
102 : * @access public
103 : */
104 : public function getContent() {
105 : // Falls keine Dateien im Zip oder zu viele Dateien (null bomb)
106 0 : if ( $this->za->numFiles < 1 || $this->za->numFiles > 10000 )
107 0 : return null;
108 :
109 : // Mögliche OS Abhängigkeiten
110 0 : $freeSpace = disk_free_space( PATH_TO_ROOT );
111 0 : $zaSize = $this->calculateSize();
112 :
113 : // Nach dem entpacken müssen noch mind. 20 MB freier Plattenplatz zur Verfügung stehen
114 0 : if ( ($freeSpace - $zaSize < 20971520))
115 0 : throw new Exception('Nicht genügend freier Festplattenspeicher');
116 :
117 : // Zip entpacken
118 0 : $this->extractZip();
119 :
120 : // In TMP_DIR die entpackten Dateien indexieren, erhählt gesamten Inhalt als String
121 0 : return $this->indexTmpFiles();
122 : }
123 :
124 : /**
125 : * Schliessen der Datei
126 : *
127 : * @access public
128 : */
129 : public function close() {
130 0 : $this->za->close();
131 0 : }
132 :
133 : /**
134 : * Temporäre Dateien entfernen
135 : *
136 : * @access public
137 : */
138 : public function cleanup() {
139 0 : if ( !is_dir(TMP_DIR) )
140 0 : return true;
141 :
142 0 : $this->deltree(TMP_DIR);
143 0 : }
144 :
145 :
146 : /**
147 : * Zip entpacken
148 : *
149 : * @access proteced
150 : * @return
151 : */
152 : protected function extractZip() {
153 0 : $this->createTempDir();
154 0 : $this->za->extractTo(TMP_DIR);
155 0 : }
156 :
157 : /**
158 : * Datei Endung ermitteln
159 : *
160 : * @access proteced
161 : * @return string
162 : */
163 : protected function getExtension( $fileName ) {
164 0 : $pathParts = pathinfo($fileName);
165 :
166 0 : return (isset($pathParts['extension']) ? $pathParts['extension'] : '');
167 : }
168 :
169 : /**
170 : * Temporäres Verzeichnis erzeugen
171 : *
172 : * @access proteced
173 : * @return string
174 : */
175 : protected function createTempDir() {
176 0 : if ( is_dir(TMP_DIR) )
177 0 : $this->cleanup();
178 :
179 0 : mkdir(TMP_DIR, 0700);
180 0 : }
181 :
182 : /**
183 : * Rekursives Löschen eins Verzeichnisses inkl. der darin enthaltenen Dateien
184 : *
185 : * @access proteced
186 : * @param $f - Verzeichnis
187 : * @return
188 : */
189 : protected function deltree( $f ) {
190 0 : if( is_dir($f) ) {
191 0 : foreach( scandir($f) as $item ) {
192 0 : if( !strcmp($item, '.') || !strcmp($item, '..') )
193 0 : continue;
194 :
195 0 : $this->deltree( $f . "/" . $item );
196 0 : }
197 :
198 0 : rmdir($f);
199 0 : }
200 : else
201 0 : unlink($f);
202 0 : }
203 :
204 : /**
205 : * Berechnet den Speicherplatz Bedarf des entpackten Zips
206 : *
207 : * @access proteced
208 : * @param $f - Verzeichnis
209 : * @return int
210 : */
211 : protected function calculateSize() {
212 0 : $zaSize = 0;
213 :
214 0 : for ( $i = 0; $i < $this->za->numFiles; $i++ ) {
215 : // Enthält alle Zip-Informationen über die archivierten Dateien
216 0 : $array = $this->za->statIndex($i);
217 :
218 0 : $zaSize += $array['size'];
219 0 : }
220 :
221 0 : return $zaSize;
222 : }
223 :
224 : /**
225 : * Rekursives durchgehen des TMP_DIR Verzeichnisses
226 : *
227 : * @access proteced
228 : * @return string
229 : */
230 : protected function indexTmpFiles() {
231 0 : $content = '';
232 :
233 0 : $sc = new IndexerStrategy();
234 0 : $fileTypes = $sc->getFileTypes();
235 :
236 0 : $files = $this->getRecursiveDirectoryList(TMP_DIR);
237 :
238 0 : foreach( $files as $file) {
239 0 : $ext = $this->getExtension($file);
240 :
241 0 : if ( array_key_exists($ext, $fileTypes) )
242 0 : $sc->usePlugin($fileTypes[$this->getExtension($file)]);
243 : else
244 0 : $sc->usePlugin('');
245 :
246 0 : $sc->open($file);
247 0 : $content .= $sc->getContent() . ' ';
248 0 : $sc->close();
249 0 : $sc->cleanup();
250 :
251 0 : }
252 :
253 0 : return $content;
254 : }
255 :
256 :
257 : /**
258 : * Rekursives durchgehen des TMP_DIR Verzeichnisses
259 : *
260 : * @access proteced
261 : * @return array
262 : */
263 : public function getRecursiveDirectoryList( $startDir ) {
264 0 : $files = array ();
265 :
266 0 : if (is_dir($startDir)) {
267 0 : $fh = opendir($startDir);
268 :
269 0 : while (($file = readdir($fh)) !== false) {
270 0 : if (strcmp($file, '.') == 0 || strcmp($file, '..') == 0)
271 0 : continue;
272 :
273 0 : $filepath = $startDir . '/' . $file;
274 :
275 0 : if (is_dir($filepath))
276 0 : $files = array_merge($files, $this->getRecursiveDirectoryList($filepath));
277 : else
278 0 : array_push($files, $filepath);
279 0 : }
280 :
281 0 : closedir($fh);
282 0 : }
283 : else
284 0 : $files = false;
285 :
286 0 : return $files;
287 : }
288 :
289 : }
290 :
|